<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010</title>

<link rel="stylesheet" href="Why%20Android%20SSL%20was%20downgraded%20from%20AES256-SHA%20to%20RC4-MD5%20in%20late%202010_pliki/style.css" type="text/css">

<link rel="stylesheet" href="Why%20Android%20SSL%20was%20downgraded%20from%20AES256-SHA%20to%20RC4-MD5%20in%20late%202010_pliki/local.css" type="text/css">





</head>
<body>

<div class="page">

<div class="pageheader">
<div class="header">
<span>
<span class="parentlinks">

<a href="http://op-co.de/blog/">op-co.de blog</a>/ 

<a href="http://op-co.de/blog/posts/">posts</a>/ 

</span>
<span class="title">
Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010

</span>
</span>

</div>


<div class="actions">
<ul>


<li><a href="http://op-co.de/blog/recentchanges/">RecentChanges</a></li>






<li><a href="http://op-co.de/blog/ikiwiki.cgi?page=posts%2Fandroid_ssl_downgrade&amp;do=comment">Comment</a></li>

</ul>
</div>




</div>


<div class="sidebar">
<p>Navigation</p>

<ul>
<li><a href="http://op-co.de/">Homepage</a></li>
<li><a href="http://op-co.de/blog/">Blog</a></li>
<li><a href="http://op-co.de/blog/posts/">Archive</a></li>
<li><a href="http://op-co.de/cgit"><code>git</code></a></li>
</ul>

<p><a href="http://op-co.de/blog/tags/">Tags</a></p>

<div class="map">
<ul>
<li><a href="http://op-co.de/blog/tags/android/" class="mapitem">android</a>
</li>
<li><a href="http://op-co.de/blog/tags/homebrew/" class="mapitem">homebrew</a>
</li>
<li><a href="http://op-co.de/blog/tags/misc/" class="mapitem">misc</a>
</li>
<li><a href="http://op-co.de/blog/tags/net/" class="mapitem">net</a>
</li>
</ul>
</div>

<p>Hackers</p>

<ul>
<li><a href="http://debugmo.de/">debugmo.de</a></li>
<li><a href="http://www.pagetable.com/">pagetable.com</a></li>
<li><a href="http://www.yosefk.com/blog/">yosefk</a></li>
<li><a href="http://www.bunniestudios.com/">bunnie</a></li>
</ul>

<p><img src="Why%20Android%20SSL%20was%20downgraded%20from%20AES256-SHA%20to%20RC4-MD5%20in%20late%202010_pliki/GL.png" alt="GL" id="gl"></p>

</div>


<div id="pagebody">

<div id="content">
<h3 id="tldr">tl;dr</h3>

<p>Android is using the combination of <a href="http://www.isg.rhul.ac.uk/tls/">horribly</a>
<a href="http://www.win.tue.nl/hashclash/rogue-ca/">broken</a> RC4 and
MD5 as the first default cipher on <strong>all SSL connections</strong>. This impacts all
apps that did not care enough to change the list of enabled ciphers (i.e.
almost all existing apps). This post investigates why RC4-MD5 is the default
cipher, and why it replaced better ciphers which were in use prior to the
Android 2.3 release in December 2010.</p>

<h3 id="pretext">Pretext</h3>

<p>Some time ago, I was adding <a href="http://aprsdroid.org/ssl/">secure authentication</a>
to my <a href="https://play.google.com/store/apps/details?id=org.aprsdroid.app">APRSdroid app</a>
for Amateur Radio geolocation. While debugging its TLS handshake, I noticed
that RC4-MD5 is leading the client's list of supported ciphers and thus wins
the negotiation. As the task at hand was about authentication, not about
secrecy, I did not care.</p>

<p>However, following <a href="http://www.theregister.co.uk/2013/09/06/nsa_cryptobreaking_bullrun_analysis/">speculations about what the NSA can decrypt</a>,
<a href="https://blog.thijsalkema.de/blog/2013/09/02/the-state-of-tls-on-xmpp-3/">xnyhps' excellent post about XMPP clients</a>
(make sure to read
<a href="https://blog.thijsalkema.de/blog/2013/08/26/the-state-of-tls-on-xmpp-1/">the</a>
<a href="https://blog.thijsalkema.de/blog/2013/08/28/the-state-of-tls-on-xmpp-2/">whole</a>
<a href="https://blog.thijsalkema.de/blog/2013/09/02/the-state-of-tls-on-xmpp-3/">series</a>)
brought it into my focus again and I seriously asked myself what reasons led
to it.</p>

<h3 id="statusquoanalysis">Status Quo Analysis</h3>

<p>First, I fired up Wireshark, started <a href="http://yaxim.org/">yaxim</a> on my Android
4.2.2 phone (CyanogenMod 10.1.3 on a Galaxy Nexus) and checked the Client Hello
packet sent. Indeed, RC4-MD5 was first, followed by RC4-SHA1:</p>



<p><img src="Why%20Android%20SSL%20was%20downgraded%20from%20AES256-SHA%20to%20RC4-MD5%20in%20late%202010_pliki/wireshark-xmpp-4.png" alt="wireshark-xmpp-4.2.2.png"></p>

<p>To quote from <a href="http://tools.ietf.org/html/rfc2246#section-7.4.1.2">RFC 2246</a>:
"<em>The CipherSuite list, passed from the client to the server in the client
hello message, contains the combinations of cryptographic algorithms supported
by the client in order of the client's preference (favorite choice first).</em>"
Thus, the server is encouraged to actually use RC4-MD5 if it is not explicitly
forbidden by its configuration.</p>

<p>I crammed out my legacy devices and cross-checked Android 2.2.1 (CyanogenMod
6.1.0 on HTC Dream), 2.3.4 (Samsung original ROM on Galaxy SII) and 2.3.7
(CyanogenMod 7 on a Galaxy 5):</p>

<table>
<tbody><tr><th>Android 2.2.1</th><th>Android 2.3.4, 2.3.7</th><th>Android 4.2.2, 4.3</th></tr>
<tr><td>DHE-RSA-AES256-SHA</td><td>RC4-MD5</td><td>RC4-MD5</td></tr>
<tr><td>DHE-DSS-AES256-SHA</td><td>RC4-SHA</td><td>RC4-SHA</td></tr>
<tr><td>AES256-SHA</td><td>AES128-SHA</td><td>AES128-SHA</td></tr>
<tr><td>EDH-RSA-DES-CBC3-SHA</td><td>DHE-RSA-AES128-SHA</td><td>AES256-SHA</td></tr>
<tr><td>EDH-DSS-DES-CBC3-SHA</td><td>DHE-DSS-AES128-SHA</td><td>ECDH-ECDSA-RC4-SHA</td></tr>
<tr><td>DES-CBC3-SHA</td><td>DES-CBC3-SHA</td><td>ECDH-ECDSA-AES128-SHA</td></tr>
<tr><td>DES-CBC3-MD5</td><td>EDH-RSA-DES-CBC3-SHA</td><td>ECDH-ECDSA-AES256-SHA</td></tr>
<tr><td>DHE-RSA-AES128-SHA</td><td>EDH-DSS-DES-CBC3-SHA</td><td>ECDH-RSA-RC4-SHA</td></tr>
<tr><td>DHE-DSS-AES128-SHA</td><td>DES-CBC-SHA</td><td>ECDH-RSA-AES128-SHA</td></tr>
<tr><td>AES128-SHA</td><td>EDH-RSA-DES-CBC-SHA</td><td>ECDH-RSA-AES256-SHA</td></tr>
<tr><td>RC2-CBC-MD5</td><td>EDH-DSS-DES-CBC-SHA</td><td>ECDHE-ECDSA-RC4-SHA</td></tr>
<tr><td>RC4-SHA</td><td>EXP-RC4-MD5</td><td>ECDHE-ECDSA-AES128-SHA</td></tr>
<tr><td>RC4-MD5</td><td>EXP-DES-CBC-SHA</td><td>ECDHE-ECDSA-AES256-SHA</td></tr>
<tr><td>RC4-MD5</td><td>EXP-EDH-RSA-DES-CBC-SHA</td><td>ECDHE-RSA-RC4-SHA</td></tr>
<tr><td>EDH-RSA-DES-CBC-SHA</td><td>EXP-EDH-DSS-DES-CBC-SHA</td><td>ECDHE-RSA-AES128-SHA</td></tr>
<tr><td>EDH-DSS-DES-CBC-SHA</td><td></td><td>ECDHE-RSA-AES256-SHA</td></tr>
<tr><td>DES-CBC-SHA</td><td></td><td>DHE-RSA-AES128-SHA</td></tr>
<tr><td>DES-CBC-MD5</td><td></td><td>DHE-RSA-AES256-SHA</td></tr>
<tr><td>EXP-EDH-RSA-DES-CBC-SHA</td><td></td><td>DHE-DSS-AES128-SHA</td></tr>
<tr><td>EXP-EDH-DSS-DES-CBC-SHA</td><td></td><td>DHE-DSS-AES256-SHA</td></tr>
<tr><td>EXP-DES-CBC-SHA</td><td></td><td>DES-CBC3-SHA</td></tr>
<tr><td>EXP-RC2-CBC-MD5</td><td></td><td>ECDH-ECDSA-DES-CBC3-SHA</td></tr>
<tr><td>EXP-RC2-CBC-MD5</td><td></td><td>ECDH-RSA-DES-CBC3-SHA</td></tr>
<tr><td>EXP-RC4-MD5</td><td></td><td>ECDHE-ECDSA-DES-CBC3-SHA</td></tr>
<tr><td>EXP-RC4-MD5</td><td></td><td>ECDHE-RSA-DES-CBC3-SHA</td></tr>
<tr><td></td><td></td><td>EDH-RSA-DES-CBC3-SHA</td></tr>
<tr><td></td><td></td><td>EDH-DSS-DES-CBC3-SHA</td></tr>
<tr><td></td><td></td><td>DES-CBC-SHA</td></tr>
<tr><td></td><td></td><td>EDH-RSA-DES-CBC-SHA</td></tr>
<tr><td></td><td></td><td>EDH-DSS-DES-CBC-SHA</td></tr>
<tr><td></td><td></td><td>EXP-RC4-MD5</td></tr>
<tr><td></td><td></td><td>EXP-DES-CBC-SHA</td></tr>
<tr><td></td><td></td><td>EXP-EDH-RSA-DES-CBC-SHA</td></tr>
<tr><td></td><td></td><td>EXP-EDH-DSS-DES-CBC-SHA</td></tr>
</tbody></table>

<p>As can be seen, Android 2.2.1 came with a set of AES256-SHA1 ciphers first,
followed by 3DES and AES128. Android 2.3 <strong>significantly reduced the
security</strong> by removing AES256 and putting the broken RC4-MD5 on the prominent
first place, followed by the not-so-much-better RC4-SHA1.</p>

<h3 id="wait...what">Wait... What?</h3>

<p>Yes, Android versions before 2.3 were using AES256 &gt; 3DES &gt; AES128 &gt; RC4, and
starting with 2.3 it was now: RC4 &gt; AES128 &gt; 3DES. Also, the recently broken
MD5 suddenly became the favorite MAC (<strong>Update:</strong>
<a href="https://news.ycombinator.com/item?id=6548545">MD5 in TLS is OK, as it is combining two different variants</a>).</p>

<p>As Android 2.3 was released in late 2010, speculations about the NSA pouring
money on Android developers to sabotage all of us poor users arose
immediately. I needed to do something, so I wrote a minimal test program
(<a href="http://duenndns.de/SSLCiphers.apk">APK</a>, <a href="http://duenndns.de/SSLCiphersProject.zip">source</a>)
and single-stepped it to find the origin of the default cipher list.</p>

<p>It turned out to be in Android's libcore package,
<tt>NativeCrypto.getDefaultCipherSuites()</tt> which returns a hardcoded
String array starting with <tt>"SSL_RSA_WITH_RC4_128_MD5"</tt>.</p>

<h3 id="divingintotheandroidsource">Diving Into the Android Source</h3>

<p>Going back on that file's change history revealed interesting things, like the
<a href="https://android.googlesource.com/platform/libcore/+/3e6dd45baa0d7f9b4fa06f4ade76e088b59cc7bf%5E%21">addition of TLS v1.1 and v1.2</a>
and its almost immediate
<a href="https://android.googlesource.com/platform/libcore/+/0731920fdf845358cc13ce78292f9e80e143f915%5E%21/">removal with a suspicious commit message</a>
(taking place between Android 4.0 and 4.1,
<a href="https://code.google.com/p/android-source-browsing/source/detail?r=d473d7ae9135c9ca149a361b78366a753e1c0d5f&amp;repo=platform--external--chromium">possible reasoning</a>),
<a href="https://android.googlesource.com/platform/libcore/+/4ae3fd787741bfe1b808f447dcb0785250024119%5E%21/">added support for Elliptic Curves and AES256</a>
in Android 3.x, and finally the
<a href="https://android.googlesource.com/platform/libcore/+/9acacc36bafda869c6e9cc63786cdddd995ca96a%5E%21">addition of our hardcoded string list</a>
sometime before Android 2.3:</p>

<pre class="hl"> public static String[] getDefaultCipherSuites() {
<span class="hl kwb">-       int ssl_ctx = SSL_CTX_new();</span>
<span class="hl kwb">-       String[] supportedCiphers = SSL_CTX_get_ciphers(ssl_ctx);</span>
<span class="hl kwb">-       SSL_CTX_free(ssl_ctx);</span>
<span class="hl kwb">-       return supportedCiphers;</span>
<span class="hl kwa">+        return new String[] {</span>
<span class="hl kwa">+            "SSL_RSA_WITH_RC4_128_MD5",</span>
<span class="hl kwa">+            "SSL_RSA_WITH_RC4_128_SHA",</span>
<span class="hl kwa">+            "TLS_RSA_WITH_AES_128_CBC_SHA",</span>
...
<span class="hl kwa">+            "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",</span>
<span class="hl kwa">+            "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"</span>
<span class="hl kwa">+        };</span>
 }
</pre>

<p>The commit message tells us: <em>We now have a default cipher suite list that is
chose to match RI behavior and priority, not based on OpenSSLs default and
priorities.</em>
Translated into English: before, we just used the list from OpenSSL (which was
really good), now we make our own list... <del> with blackjack! ...and
hookers!</del> with RC4! ...and MD5!</p>

<p>The test suite comes with another hint: </p>

<pre class="hl"><span class="hl slc">// Note these are added in priority order as defined by RI 6 documentation.</span>
</pre>

<p>That RI 6 for sure has nothing to do with
<a href="http://en.m.wikipedia.org/wiki/Secret_Intelligence_Service">MI 6</a>, but stands
for <em>Reference Implementation</em>, the Sun (now Oracle) Java SDK version 6.</p>

<p>So what the fine Google engineers did to reduce our security was merely to
copy what was there,
<a href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider">defined by the inventors of Java</a>!</p>

<h3 id="cipherorderinthejavaruntime">Cipher Order in the Java Runtime</h3>

<p>In the Java reference implementation, the code responsible for creating the
cipher list is split into two files. First, a priority-ordered set of ciphers
is constructed in the
<a href="http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/77af6e10b333/src/share/classes/sun/security/ssl/CipherSuite.java">CipherSuite</a> class:</p>

<pre class="hl"><span class="hl slc">// Definition of the CipherSuites that are enabled by default.</span>
<span class="hl slc">// They are listed in preference order, most preferred first.</span>
<span class="hl kwb">int</span> p <span class="hl sym">=</span> DEFAULT_SUITES_PRIORITY <span class="hl sym">*</span> <span class="hl num">2</span><span class="hl sym">;</span>

<span class="hl kwd">add</span><span class="hl sym">(</span><span class="hl str">"SSL_RSA_WITH_RC4_128_MD5"</span><span class="hl sym">,</span> <span class="hl num">0x0004</span><span class="hl sym">, --</span>p<span class="hl sym">,</span> K_RSA<span class="hl sym">,</span> B_RC4_128<span class="hl sym">,</span> N<span class="hl sym">);</span>
<span class="hl kwd">add</span><span class="hl sym">(</span><span class="hl str">"SSL_RSA_WITH_RC4_128_SHA"</span><span class="hl sym">,</span> <span class="hl num">0x0005</span><span class="hl sym">, --</span>p<span class="hl sym">,</span> K_RSA<span class="hl sym">,</span> B_RC4_128<span class="hl sym">,</span> N<span class="hl sym">);</span>
<span class="hl sym">...</span>
</pre>

<p>Then, all enabled ciphers with sufficient priority are added to the list for
<a href="http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/77af6e10b333/src/share/classes/sun/security/ssl/CipherSuiteList.java"><tt>CipherSuiteList.getDefault()</tt></a>.
The cipher list has not experienced relevant changes since the initial import
of Java 6 into Hg, when the OpenJDK was brought to life.</p>

<p>Going back in time reveals that even in the 1.4.0 JDK, the first one
incorporating the <a href="http://en.wikipedia.org/wiki/JSSE">JSEE</a> extension for
SSL/TLS, the list was more or less the same:</p>

<table>
<tbody><tr><th>Java 1.4.0 (2002)</th><th>Java 1.4.2_19, 1.5.0 (2004)</th><th>Java 1.6 (2006)</th></tr>
<tr><td>SSL_RSA_WITH_RC4_128_SHA</td><td>SSL_RSA_WITH_RC4_128_MD5</td><td>SSL_RSA_WITH_RC4_128_MD5</td></tr>
<tr><td>SSL_RSA_WITH_RC4_128_MD5</td><td>SSL_RSA_WITH_RC4_128_SHA</td><td>SSL_RSA_WITH_RC4_128_SHA</td></tr>
<tr><td>SSL_RSA_WITH_DES_CBC_SHA</td><td>TLS_RSA_WITH_AES_128_CBC_SHA</td><td>TLS_RSA_WITH_AES_128_CBC_SHA</td></tr>
<tr><td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td><td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td><td>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</td></tr>
<tr><td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td><td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td><td>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</td></tr>
<tr><td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td><td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td><td>SSL_RSA_WITH_3DES_EDE_CBC_SHA</td></tr>
<tr><td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td><td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td><td>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</td></tr>
<tr><td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td><td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td><td>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</td></tr>
<tr><td>SSL_RSA_WITH_NULL_MD5</td><td>SSL_RSA_WITH_DES_CBC_SHA</td><td>SSL_RSA_WITH_DES_CBC_SHA</td></tr>
<tr><td>SSL_RSA_WITH_NULL_SHA</td><td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td><td>SSL_DHE_RSA_WITH_DES_CBC_SHA</td></tr>
<tr><td>SSL_DH_anon_WITH_RC4_128_MD5</td><td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td><td>SSL_DHE_DSS_WITH_DES_CBC_SHA</td></tr>
<tr><td>SSL_DH_anon_WITH_DES_CBC_SHA</td><td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td><td>SSL_RSA_EXPORT_WITH_RC4_40_MD5</td></tr>
<tr><td>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</td><td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td><td>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</td></tr>
<tr><td>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</td><td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td><td>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</td></tr>
<tr><td>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</td><td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td><td>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</td></tr>
<tr><td></td><td></td><td>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</td></tr>
</tbody></table>



<p>The original list resembles the <a href="http://tools.ietf.org/html/rfc2246#appendix-A.5">CipherSpec definition in RFC 2246</a>
 from 1999, sorted numerically with the NULL and 40-bit ciphers moved 
down. Somewhere between the first release and 1.4.2, DES was deprecated,
 TLS was
added to the mix (bringing in AES) and MD5 was pushed in front of SHA1 
(which makes one
wonder why). After that, the only chage was the addition of
<tt>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</tt>, which is not a cipher but just
an information token for the server.</p>

<p>Java 7 <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider">added Elliptic Curves and significantly improved the cipher list</a>
in 2011, but Android is based on JDK 6, making the effective default cipher
list over 10 years old now.</p>

<h3 id="conclusion">Conclusion</h3>

<p>The cipher order on the vast majority of Android devices was defined by Sun in
2002 and taken over into the Android project in 2010 as an attempt to improve
compatibility. RC4 is considered problematic since
<a href="http://www.wisdom.weizmann.ac.il/%7Eitsik/RC4/Papers/bc_rc4.ps">2001</a> (remember
<a href="http://en.m.wikipedia.org/wiki/Wired_Equivalent_Privacy">WEP</a>?), MD5 was
broken in <a href="http://www.win.tue.nl/hashclash/rogue-ca/">2009</a>.</p>

<p>The change from the strong OpenSSL cipher list to a hardcoded one starting
with weak ciphers is either a sign of horrible ignorance, security
incompetence or a clever disguise for an NSA-influenced manipulation - you
decide! (This was before
<a href="http://vnhacker.blogspot.de/2011/09/beast.html">BEAST</a> made the other ciphers
in TLS <em>less secure</em> in 2011 and RC4 gained momentum again)</p>

<p>All that notwithstanding, now is the time to get rid of RC4-MD5, in your
applications as well as in the Android core! Call your representative on the
Google board and let them know!</p>

<h3 id="appendixa:makingyourappmoresecure">Appendix A: Making your app more secure</h3>

<p>If your app is only ever making contact to your own server, feel free to
choose the best cipher that fits into your CPU budget! Otherwise, it is hard
to give generic advice for an app to support a wide variety of different
servers without producing obscure connection errors.</p>

<p>Server operators should read the excellent
<a href="https://www.ssllabs.com/projects/best-practices/index.html">best practices document by SSLLabs</a>. </p>

<h4 id="changingtheclientcipherlist">Changing the client cipher list</h4>

<p>For client developers, I am recycling the well-motivated
<a href="https://briansmith.org/browser-ciphersuites-01.html">browser cipher suite proposal</a>
written by Brian Smith at Mozilla, even though I share
<a href="https://www.schneier.com/blog/archives/2013/09/the_nsas_crypto_1.html">Bruce Schneier's scepticism on EC cryptography</a>.
The following is a subset of Brian's ciphers which are supported on Android
4.2.2, and the last three ciphers are named <tt>SSL_</tt> instead of
<tt>TLS_</tt>.</p>

<pre class="hl"><span class="hl slc">// put this in a place where it can be reused</span>
<span class="hl kwa">static final</span> <span class="hl kwc">String</span> ENABLED_CIPHERS<span class="hl sym">[] = {</span>
        <span class="hl str">"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_DHE_RSA_WITH_AES_256_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_DHE_DSS_WITH_AES_128_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_ECDHE_RSA_WITH_RC4_128_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_RSA_WITH_AES_128_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"TLS_RSA_WITH_AES_256_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"SSL_RSA_WITH_3DES_EDE_CBC_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"SSL_RSA_WITH_RC4_128_SHA"</span><span class="hl sym">,</span>
        <span class="hl str">"SSL_RSA_WITH_RC4_128_MD5"</span><span class="hl sym">,</span>
    <span class="hl sym">};</span>

<span class="hl slc">// get a new socket from the factory</span>
<span class="hl kwc">SSLSocket</span> s <span class="hl sym">= (</span><span class="hl kwc">SSLSocket</span><span class="hl sym">)</span>sslcontext<span class="hl sym">.</span><span class="hl kwd">getSocketFactory</span><span class="hl sym">().</span><span class="hl kwd">createSocket</span><span class="hl sym">(</span>host<span class="hl sym">,</span> port<span class="hl sym">);</span>
<span class="hl slc">// IMPORTANT: set the cipher list before calling getSession(),</span>
<span class="hl slc">// startHandshake() or reading/writing on the socket!</span>
s<span class="hl sym">.</span><span class="hl kwd">setEnabledCipherSuites</span><span class="hl sym">(</span>ENABLED_CIPHERS<span class="hl sym">);</span>
<span class="hl sym">...</span>
</pre>

<h4 id="usetlsv1.2">Use TLS v1.2!</h4>

<p>By default, TLS version 1.0 is used, and the more recent protocol versions are
disabled. Some servers used to be
<a href="https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371">broken</a> when
contacted using v1.2, so this approach seemed a good conservative choice
<a href="https://code.google.com/p/android-source-browsing/source/detail?r=d473d7ae9135c9ca149a361b78366a753e1c0d5f&amp;repo=platform--external--chromium">over a year ago</a>.</p>

<p>At least for XMPP, an
<a href="https://datatracker.ietf.org/doc/draft-saintandre-xmpp-tls/?include_text=1">attempt to enforce TLS v1.2</a>
is being made. You can follow with your own app easily:</p>

<pre class="hl"><span class="hl slc">// put this in a place where it can be reused</span>
<span class="hl kwa">static final</span> <span class="hl kwc">String</span> ENABLED_PROTOCOLS<span class="hl sym">[] = {</span>
        <span class="hl str">"TLSv1.2"</span><span class="hl sym">,</span> <span class="hl str">"TLSv1.1"</span><span class="hl sym">,</span> <span class="hl str">"TLSv1"</span>
    <span class="hl sym">};</span>

<span class="hl slc">// put this right before setEnabledCipherSuites()!</span>
s<span class="hl sym">.</span><span class="hl kwd">setEnabledProtocols</span><span class="hl sym">(</span>ENABLED_PROTOCOLS<span class="hl sym">);</span>
</pre>

<h4 id="usenetcipher">Use NetCipher!</h4>

<p><a href="https://guardianproject.info/code/netcipher/">NetCipher</a> is an Android
library made by the <a href="https://guardianproject.info/">Guardian Project</a> to
improve network security for mobile apps. It comes with a StrongTrustManager
to do more thorough certificate checks, an independent Root CA store, and code
to easily route your traffic through
<a href="https://www.torproject.org/">the Tor network</a> using <a href="https://guardianproject.info/apps/orbot/">Orbot</a>.</p>

<h4 id="useandroidpinning">Use AndroidPinning!</h4>

<p><a href="https://github.com/moxie0/AndroidPinning">AndroidPinning</a> is another Android
library, written by <a href="http://www.thoughtcrime.org/">Moxie Marlinspike</a> to allow
pinning of server certificates, improving security against government-scale
MitM attacks. Use this if your app is made to communicate with a specific
server!</p>

<h4 id="usememorizingtrustmanager">Use MemorizingTrustManager!</h4>

<p><a href="https://github.com/ge0rg/MemorizingTrustManager/">MemorizingTrustManager</a> by
yours truly is yet another Android library. It allows your app to ask the user
if they want to trust a given self-signed/untrusted certificate, improving
support for regular connections to private services. If you are writing an
XMPP client or a private cloud sync app, use this!</p>

<h3 id="appendixb:appsthatdocare">Appendix B: Apps that do care</h3>

<h4 id="androidbrowser">Android Browser</h4>

<p>Checks of the default Android Browser revealed that at least until Android
2.3.7 the Browser was using the default cipher list of the OS, participating
in the RC4 regression.</p>

<p>As of 4.2.2, the Browser comes with a longer, better, stronger cipher list:</p>

<p><tt>ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA SRP-DSS-AES-256-CBC-SHA
SRP-RSA-AES-256-CBC-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA
ECDH-RSA-AES256-SHA ECDH-ECDSA-AES256-SHA AES256-SHA ECDHE-RSA-DES-CBC3-SHA
ECDHE-ECDSA-DES-CBC3-SHA SRP-DSS-3DES-EDE-CBC-SHA SRP-RSA-3DES-EDE-CBC-SHA
EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA
ECDH-ECDSA-DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA SRP-DSS-AES-128-CBC-SHA SRP-RSA-AES-128-CBC-SHA
DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-AES128-SHA
ECDH-ECDSA-AES128-SHA AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-RC4-SHA
ECDH-RSA-RC4-SHA ECDH-ECDSA-RC4-SHA RC4-SHA RC4-MD5</tt></p>

<h4 id="sendinyourapp">Send In Your App!</h4>

<p>If you have an Android app with a significant user base that has a better
cipher list, let me know and I will add it to the list.</p>

<h3 id="furtherreading">Further Reading</h3>

<ul>
<li><a href="https://www.imperialviolet.org/2013/01/13/rwc03.html">Real World Crypto 2013</a> by Adam Langley from Google</li>
<li><a href="http://bristolcrypto.blogspot.fr/2013/08/why-does-web-still-run-on-rc4.html">Why does the web still run on RC4?</a> by Luke Mather</li>
<li><em><a href="https://news.ycombinator.com/item?id=6548391">HN comments</a></em></li>
</ul>

</div>



<div id="comments">




<div class="addcomment">
<a href="http://op-co.de/blog/ikiwiki.cgi?page=posts%2Fandroid_ssl_downgrade&amp;do=comment">Add a comment</a>
</div>

</div>



</div>

<div id="footer" class="pagefooter">

<div id="pageinfo">


<div class="tags">
Tags:

<a href="http://op-co.de/blog/tags/android/" rel="tag">android</a>

</div>








<div class="pagedate">
Last edited <span class="date">2013-10-14 21:18:58</span>
<!-- Created <span class="date">2013-10-14 19:06:48</span> -->
</div>

</div>


<!-- from op-co.de blog -->
</div>

</div>



</body></html>